﻿Imports Microsoft.Win32
Imports System
Imports System.Runtime.CompilerServices
Imports System.Threading
Imports System.Workflow.Runtime

Namespace System.Workflow.Runtime.DebugEngine
    Friend NotInheritable Class DebugControllerThread
        ' Methods
        Public Sub New()
            Me.threadInitializedEvent.Reset
            Me.controllerThread = New Thread(New ParameterizedThreadStart(AddressOf Me.ControllerThreadFunction))
            Me.controllerThread.IsBackground = True
            Me.controllerThread.Priority = ThreadPriority.Lowest
            Me.controllerThread.Name = "__dct__"
        End Sub

        Private Sub ControllerThreadFunction(ByVal instanceTable As Object)
            Try 
                Dim frame As IExpressionEvaluationFrame = Nothing
                Try 
                    Dim key As RegistryKey = Registry.LocalMachine.OpenSubKey(RegistryKeys.DebuggerSubKey)
                    If (Not key Is Nothing) Then
                        Dim str As String = [TryCast](key.GetValue(DebugControllerThread.ExpressionEvaluationFrameTypeName, String.Empty),String)
                        If (Not String.IsNullOrEmpty(str) AndAlso (Not Type.GetType(str) Is Nothing)) Then
                            frame = [TryCast](Activator.CreateInstance(Type.GetType(str)),IExpressionEvaluationFrame)
                        End If
                    End If
                Catch obj1 As Object
                Finally
                    If (frame Is Nothing) Then
                        frame = [TryCast](Activator.CreateInstance(Type.GetType("Microsoft.Workflow.DebugEngine.ExpressionEvaluationFrame, Microsoft.Workflow.ExpressionEvaluation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")),IExpressionEvaluationFrame)
                    End If
                End Try
                If (Not frame Is Nothing) Then
                    frame.CreateEvaluationFrame(DirectCast(instanceTable, IInstanceTable), DirectCast(Delegate.CreateDelegate(GetType(DebugEngineCallback), Me, "ExpressionEvaluationFunction"), DebugEngineCallback))
                End If
            Catch obj2 As Object
            End Try
        End Sub

        Public Sub ExpressionEvaluationFunction()
            Me.threadId = NativeMethods.GetCurrentThreadId
            Me.threadInitializedEvent.Set
            [Using] New DebuggerThreadMarker
                Do While Me.runThread
                    Try 
                        If (IntPtr.Size = 8) Then
                            Thread.Sleep(-1)
                        Else
                            Do While Me.runThread
                            Loop
                        End If
                        [Continue] Do
                    Catch exception1 As ThreadAbortException
                        Throw
                    Catch obj1 As Object
                        [Continue] Do
                    End Try
                Loop
            End [Using]
        End Sub

        Public Sub RunThread(ByVal instanceTable As IInstanceTable)
            If (Not Me.controllerThread Is Nothing) Then
                Me.runThread = True
                Me.controllerThread.Start(instanceTable)
                Me.threadInitializedEvent.WaitOne
            End If
        End Sub

        Public Sub StopThread()
            Try 
                If (Not Me.controllerThread Is Nothing) Then
                    Me.runThread = False
                    Thread.Sleep(10)
                    If (Me.controllerThread.IsAlive AndAlso (IntPtr.Size = 8)) Then
                        Do While (Me.controllerThread.ThreadState = ThreadState.WaitSleepJoin)
                            Me.controllerThread.Start
                            Me.controllerThread.Join
                        Loop
                    Else
                        Me.controllerThread.Join
                    End If
                End If
            Catch exception1 As ThreadStateException
            Finally
                Me.controllerThread = Nothing
            End Try
            Me.controllerThread = Nothing
            Me.threadId = 0
            Me.threadInitializedEvent = Nothing
        End Sub


        ' Properties
        Public ReadOnly Property ManagedThreadId As Integer
            Get
                Return Me.controllerThread.ManagedThreadId
            End Get
        End Property

        Public ReadOnly Property ThreadId As Integer
            Get
                Return Me.threadId
            End Get
        End Property


        ' Fields
        Private controllerThread As Thread
        Private Shared ReadOnly ExpressionEvaluationFrameTypeName As String = "ExpressionEvaluationFrameTypeName"
        Private runThread As Boolean ModReq(IsVolatile)
        Private threadId As Integer
        Private threadInitializedEvent As ManualResetEvent = New ManualResetEvent(False)
    End Class
End Namespace

